package com.ht.config.quartz;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ht.module.job.entity.JobLog;
import com.ht.module.job.mapper.JobLogMapper;
import jakarta.annotation.Resource;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * Quartz 通用 Job 类（反射加载）
 */
public class DynamicClassJob implements Job {

    @Resource
    private JobLogMapper jobLogMapper;

    @Override
    public void execute(JobExecutionContext context){
        JobDataMap dataMap = context.getMergedJobDataMap();
        String jobId = dataMap.getString("jobId");
        String jobName = dataMap.getString("jobName");
        String jobGroup = dataMap.getString("jobGroup");
        String jobClassName = dataMap.getString("jobClass");
        String jobParamsJson = dataMap.getString("jobParams");

        JobLog log = new JobLog();
        log.setJobId(jobId);
        log.setJobName(jobName);
        log.setJobGroup(jobGroup);
        log.setStartTime(LocalDateTime.now());

        try {
            // 反射加载
            Class<?> clazz = Class.forName(jobClassName);
            Object instance = clazz.getDeclaredConstructor().newInstance();

            if (instance instanceof Runnable) {
                ((Runnable) instance).run();
            } else if (instance instanceof ParamJob) {
                Map<String, Object> params = new ObjectMapper().readValue(jobParamsJson, Map.class);
                ((ParamJob) instance).executeWithParams(params);
            } else {
                throw new RuntimeException("任务类必须实现 Runnable 或 ParamJob 接口");
            }

            log.setStatus("SUCCESS");
        } catch (Exception e) {
            log.setStatus("FAIL");
            log.setErrorMessage(e.getMessage());
        } finally {
            log.setEndTime(LocalDateTime.now());
            jobLogMapper.insert(log);
        }
    }

    public interface ParamJob {
        void executeWithParams(Map<String, Object> params);
    }
}